using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;

using NUnitTestHelper;

namespace NUnitTestForFTAC
{
    class Program
    {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        /// <returns>0 : success; -1 : no arguments; failed count : failed</returns>
        [STAThread]
        static int Main(string[] args)
        {
            NUnitBuildOptions nuintOptions = new NUnitBuildOptions();
            // TODO: how to get this value? by param or hard-code?
            nuintOptions.NUnitExePath = @"C:\Program Files\NUnit 2.4.8\bin\nunit-console.exe";

            Arguments arguments = new Arguments(args);

            if (arguments["Proj"] != null)
            {
                nuintOptions.NUnitConfigPath = arguments["Proj"];

                // Get the path where the results file is located
                string sTestResultsPath = nuintOptions.NUnitConfigPath;

                // Find the end of the configuration file path
                int index = sTestResultsPath.IndexOf(" ");

                // Get just the configuration file path
                if (index > 0)
                    sTestResultsPath = sTestResultsPath.Remove(index);

                // Get just the path with the configuration file removed
                index = sTestResultsPath.LastIndexOf("\\");
                sTestResultsPath = sTestResultsPath.Remove(index);

                // Create path to the TestResult file by combining path and the file name
                sTestResultsPath = Path.Combine(sTestResultsPath, "TestResult.xml");

                // Delete the existing NUnit TestResult file if it exists
                if (File.Exists(sTestResultsPath))
                {
                    File.Delete(sTestResultsPath);
                    //Console.WriteLine("Test result file deleted.");
                }

                try
                {
                    // create a process, execute the command, and capture the output
                    ProcessStartInfo psi = new ProcessStartInfo(nuintOptions.NUnitExePath, nuintOptions.NUnitConfigPath);

                    psi.RedirectStandardOutput = true;
                    psi.RedirectStandardError = true;
                    psi.RedirectStandardInput = true;
                    psi.WindowStyle = ProcessWindowStyle.Hidden;
                    psi.UseShellExecute = false;
                    psi.CreateNoWindow = true;
                    psi.WorkingDirectory = Path.GetDirectoryName(nuintOptions.NUnitExePath);

                    // redirect test result output, or it will be put under psi.WorkingDirectory folder
                    psi.Arguments += @" /xml=" + sTestResultsPath;

                    System.Diagnostics.Process p = new System.Diagnostics.Process();
                    p.StartInfo = psi;

                    // Set our event handler to asynchronously read the output.
                    // Update listeners with Output
                    //p.OutputDataReceived += new DataReceivedEventHandler(PrePostProcessingOutputHandler);

                    string stdOut = string.Empty;
                    try
                    {
                        Console.WriteLine("************ Begin Unit Testing Report ************");
                        Console.WriteLine(string.Format("Executing Command: \"{0} {1}\"...\r\n\r\n", psi.FileName, psi.Arguments));

                        p.Start();

                        // Start the asynchronous read of the output stream.
                        p.BeginOutputReadLine();

                        p.WaitForExit();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                    if (p.ExitCode != 0)
                        Console.WriteLine(string.Format("Unit Testing Report RETURNED ERRORCODE={0}\r\n", p.ExitCode));
                    else
                        Console.WriteLine("Unit Testing Report Succeeded.");

                    // parse the xml report
                    NUnitResultsParser resultsParse = new NUnitResultsParser(sTestResultsPath);
                    string sTestResults = resultsParse.GetTestResults();
                    Console.WriteLine(sTestResults);

                    if (resultsParse.FailuresCount > 0)
                        Environment.Exit(resultsParse.FailuresCount);

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            else
                Environment.Exit(-1); // param error

            //if(arguments["output"] != null )
            //    nuintOptions.

            //Console.Read();
            return 0;
        }
    }
}
